package P007_IncreaseI;

import org.junit.Test;

import java.util.Random;

/**
 * 莫让常量蜕变成变量
 * @author xufy1
 */
public class IncreaseI {


    @Test
    public  void test1() {
        int a = 0;
        // a++ 先赋值，后加1
        int b = a++;
        // ++a 先加1，后赋值
        int c = ++a;
        System.out.println("a=" + a + "  ,b=" + b + "  ,c=" + c);

        /**
         * 1. jvm 把count的值 拷贝到临时变量区
         * 2. count值加1，count=1;
         * 3. 返回临时变量区的值，此时值为0；
         * 4. 返回值赋值给count,此时count=0;
         */
        int count = 0;
        for (int i = 0; i < 5; i++) {
            count = count++;
        }
        //输出结果为0
        System.out.println("count=" + count);

        int count1 = 0;
        for (int j = 0; j < 5; j++) {
            count1 = ++count1;
        }
        //输出结果为5
        System.out.println("count1 = " + count1);

        int n=0;
        int m = 10;
        //m=10
        m = m++;
        n=m++;
        System.out.println("值m=" + m);

        int i = 0;
        int sum = (i++) + (i++);
        System.out.println("值sum=" + sum);
    }

    //count = count++;
    public static int mockAdd(int count) {
        int temp = count;
        count = count + 1;
        return temp;
    }
    //count = ++count;
    public static int mockAdd2(int count) {
        count = count + 1;
        int temp = count;
        return temp;
    }

    // i++, 可看作如下操作 读-修改-写;
    public static int autoAdd(int count) {
        int temp2 = count;
        temp2 = count + 1;
        return temp2;
    }
    // ++i, 可看作如下操作 修改-读-写;
    public static int autoAdd2(int count) {
        count = count + 1;
        int temp2 = count;
        return temp2;
    }
    //线程安全问题：
    /**
     * 1）如果i是局部变量（在方法里定义的），那么是线程安全的。因为局部变量是线程私有的
     * 2）如果i是全局变量（类的成员变量），那么是线程不安全的。因为如果是全局变量的话，同一进程中的不同线程都有可能访问到。
     * 如果有大量线程同时执行i++操作，i变量的副本拷贝到每个线程的线程栈，当同时有两个线程栈以上的线程读取线程变量，
     * 假如此时是1的话，那么同时执行i++操作，再写入到全局变量，最后两个线程执行完，i会等于3而不会是2，所以，出现不安全性。
     */
}
